package client;

import java.rmi.*;
import java.util.*;
import javax.naming.*;

import service.Product;
import service.Warehouse;


/**
 * The client for the warehouse program.
 */
public class WarehouseClient {
    public static void main(String[] args) throws NamingException, RemoteException {
	// Instruct the security manager to read the policy file by setting
	// java.securiy.policy property.
	// Alternatively on the command line: -Djava.security.policy=rmi.policy
	System.setProperty("java.security.policy", "client.policy");
	System.setSecurityManager(new SecurityManager());
	Context namingContext = new InitialContext();

	System.out.print("RMI registry bindings: ");
	// Enumerate all registered RMI objects
	// NameClassPair is a helper that contains both the name of the bound object 
	// and the name of its class.
	NamingEnumeration<NameClassPair> e = namingContext.list("rmi://localhost/");
	// Display the name of all registered objects.
	while (e.hasMore())
	    System.out.println(e.next().getName());

	
	// Get stub object for Warehouse, by specifying the server and the remote object name.
	// The returned stub is a proxy object used by the client to invoke the remote object.
	// It resides on the client machine. It knows how to contact the server over the network.
	String url = "rmi://localhost/central_warehouse";
	Warehouse centralWarehouse = (Warehouse) namingContext.lookup(url);

	Scanner in = new Scanner(System.in);
	System.out.print("Enter keywords: ");
	List<String> keywords = Arrays.asList(in.nextLine().split("\\s+"));
	
	// The stub method on the client builds an information block that consists of:
	// - an identifier of the remote object to be used
	// - a description of the method to be called
	// - the parameters
	// It then sends this information to the server.
	// The process of encoding the paramaters is called parameter marshalling:
	// it consists in converting them into a format suitable for transport from
	// one virtual machine to another (block of bytes). Objects are encoded with 
	// the serialization mechanism.
	Product prod = centralWarehouse.getProduct(keywords);
	
	// Invoke the remote getPrice method on the remote object via the stub hold by the client.
	System.out.println(prod.getDescription() + ": " + prod.getPrice());
	in.close();
    }
}
